package com.example.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.Tuser;
import com.example.exception.CustomException;
import com.example.service.LogService;
import com.example.service.TuserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("//tuser")
public class TuserController {
    public static final ConcurrentHashMap<String, Tuser> MAP = new ConcurrentHashMap<String, Tuser>();

    @Resource
    private TuserService tuserService;

    @Resource
    private LogService logService;
    @Resource
    private HttpServletRequest request;

    public Tuser getUser() {
        Tuser tuser = (Tuser) request.getSession().getAttribute("tuser");
        if (tuser == null) {
            throw new CustomException("-1", "请登录");
        }
        return tuser;
    }


    /**
     * 登录
     *
     * @param tuser
     * @param request
     * @return
     */
    @PostMapping("/login")
    public Result<Tuser> login(@RequestBody Tuser tuser, HttpServletRequest request) {
        Tuser res = tuserService.login(tuser);
        request.getSession().setAttribute("tuser", res);
        MAP.put(res.getUsername(), res);
        logService.log(StrUtil.format("用户 {} 登录系统", tuser.getUsername()));
        return Result.success(res);
    }

    /**
     * 注册
     *
     * @param tuser
     * @param request
     * @return
     */
    @PostMapping("/register")
    public Result<Tuser> register(@RequestBody Tuser tuser, HttpServletRequest request) {
        if (tuser.getPassword() == null) {
            tuser.setPassword("123456");
        }
        Tuser dbUser = tuserService.register(tuser);
        request.getSession().setAttribute("tuser", tuser);
        logService.log(StrUtil.format("用户 {} 注册账号成功", tuser.getUsername()));
        return Result.success(dbUser);
    }

    @GetMapping("/logout")
    public Result<?> logout(HttpServletRequest request) {
        Tuser tuser = (Tuser) request.getSession().getAttribute("tuser");
        if (tuser != null) {
            logService.log(StrUtil.format("用户 {} 退出系统", tuser.getUsername()));
            request.getSession().removeAttribute("tuser");
            MAP.remove(tuser.getUsername());
        }
        return Result.success();
    }

//    @GetMapping("/online")
//    public Result<Collection<Tuser>> online(HttpServletRequest request) {
//        return Result.success(MAP.values());
//    }
//
//    @GetMapping("/session")
//    public Result<Tuser> session() {
//        return Result.success(getUser());
//    }

    @PostMapping
    public Result<?> save(@RequestBody Tuser tuser) {
        if (tuser.getPassword() == null) {
            tuser.setPassword("123456");
        }
        logService.log(StrUtil.format("新增用户：{} ", tuser.getUsername()));
        return Result.success(tuserService.save(tuser));
    }

    @PutMapping
    public Result<?> update(@RequestBody Tuser tuser) {
        logService.log(StrUtil.format("更新用户：{} ", tuser.getUsername()));
        return Result.success(tuserService.updateById(tuser));
    }

    @DeleteMapping("/{id}")
    public Result<?> delete(@PathVariable Long id) {
        Tuser tuser = tuserService.getById(id);
        logService.log(StrUtil.format("删除用户 {} ", tuser.getUsername()));
        tuserService.removeById(id);
        return Result.success();
    }

    @GetMapping("/{id}")
    public Result<Tuser> findById(@PathVariable Long id) {
        return Result.success(tuserService.getById(id));
    }

    @GetMapping("/detail/{username}")
    public Result<Tuser> findByUsername(@PathVariable String username) {
        return Result.success(tuserService.getbyUsername(username));
    }

    @GetMapping
    public Result<List<Tuser>> findAll() {
        return Result.success(tuserService.list( Wrappers.<Tuser>lambdaQuery().ne(Tuser::getUsername, "admin")));
    }

    @GetMapping("/page")
    public Result<IPage<Tuser>> findPage(@RequestParam(required = false, defaultValue = "") String name,
                                         @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                         @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        LambdaQueryWrapper<Tuser> wrapper = Wrappers.<Tuser>lambdaQuery().ne(Tuser::getUsername, "admin").like(Tuser::getUsername, name).orderByDesc(Tuser::getId);
        return Result.success(tuserService.page(new Page<>(pageNum, pageSize), wrapper));
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {

        List<Map<String, Object>> list = CollUtil.newArrayList();

        List<Tuser> all = tuserService.list();
        for (Tuser tuser : all) {
            Map<String, Object> row1 = new LinkedHashMap<>();
            row1.put("名称", tuser.getUsername());
            row1.put("手机", tuser.getPhone());
            row1.put("邮箱", tuser.getEmail());
            list.add(row1);
        }

        // 2. 写excel
//        ExcelWriter writer = ExcelUtil.getWriter(true);
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(list, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(System.out);
    }

    @GetMapping("/upload/{fileId}")
    public Result<?> upload(@PathVariable String fileId) {
        String basePath = System.getProperty("tuser.dir") + "/src/main/resources/static/file/";
        List<String> fileNames = FileUtil.listFileNames(basePath);
        String file = fileNames.stream().filter(name -> name.contains(fileId)).findAny().orElse("");
        List<List<Object>> lists = ExcelUtil.getReader(basePath + file).read(1);
        List<Tuser> saveList = new ArrayList<>();
        for (List<Object> row : lists) {
            Tuser tuser = new Tuser();
            tuser.setUsername((String) row.get(0));
            tuser.setEmail((String) row.get(2));
            tuser.setPhone((String) row.get(3));
            saveList.add(tuser);
        }
        tuserService.saveBatch(saveList);
        return Result.success();
    }

}
